﻿#include "dingdanservice.h"
#include <QMessageBox>
#include "tools.h"
#include "user.h"

DingdanService::DingdanService(QObject *parent) : QObject(parent)
{

}

void DingdanService::saveDingdan(QWidget *widget, Dingdan &dingdan){
    if(dingdan.targetUsername.isEmpty()){
        if(dingdan.type == Dingdan::SaleOut || dingdan.type == Dingdan::SaleBack){
            QMessageBox::warning(widget, "警告", "未选择客户！");
        }else{
            QMessageBox::warning(widget, "警告", "未选择供应商！");
        }
        return;
    }

    if(dingdan.details.size() == 0){
        QMessageBox::warning(widget, "警告", "未选择商品！");
        return;
    }

    dingdan.sourceUsername = User::getUsername();
    dingdan.sourceCompanyId = User::getCompanyId();
    dingdan.opNickName = User::getNickName();

    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        emit this->saveDingdanSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->saveDingdan(dingdan);
}

void DingdanService::deleteDingdan(QWidget *widget, Dingdan &dingdan){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        emit this->deleteDingdanSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->deleteDingdan(User::getUsername(), dingdan.dingdanId);
}

void DingdanService::getDingdans(QWidget *widget, Dingdan::DingdanType type, Dingdan::DingdanState state){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray dingdanArr = data.value("dingdans").toArray();
        QList<Dingdan*> dingdans;
        for(QJsonValue obj:dingdanArr){
            Dingdan *dingdan = new Dingdan();
            dingdan->loadFromJsonObject(obj.toObject());
            dingdans.append(dingdan);
        }
        emit this->getDingdansSuccess(dingdans);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getDingdans(User::getUsername(), type, state);
}

void DingdanService::getDingdanDetails(QWidget *widget, QString dingdanId){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonObject dingdanObj = data.value("dingdan").toObject();
        QJsonArray dingdanDetailArr = data.value("details").toArray();

        Dingdan *dingdan = new Dingdan(dingdanObj);
        QList<DingdanDetail*> details;
        for(QJsonValue obj:dingdanDetailArr){
            DingdanDetail *detail = new DingdanDetail();
            detail->loadFromJsonObject(obj.toObject());
            details.append(detail);
        }
        dingdan->details = details;
        emit this->getDingdanInfoSuccess(dingdan);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getDingdanDetails(User::getUsername(), dingdanId);
}

void DingdanService::getDingdanDetails(QWidget *widget, Dingdan *dingdan){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray dingdanDetailArr = data.value("details").toArray();
        QList<DingdanDetail*> details;
        for(QJsonValue obj:dingdanDetailArr){
            DingdanDetail *detail = new DingdanDetail();
            detail->loadFromJsonObject(obj.toObject());
            details.append(detail);
        }
        dingdan->details = details;
        emit this->getDingdanDetailSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getDingdanDetails(dingdan->sourceUsername, dingdan->dingdanId);
}

void DingdanService::calculateDingdan(
        QWidget *widget,
        QPushButton *button,
        Dingdan &dingdan){

    dingdan.sourceUsername = User::getUsername();
    dingdan.sourceCompanyId = User::getCompanyId();
    dingdan.opNickName = User::getNickName();

    if(dingdan.details.size() == 0){
        QMessageBox::warning(widget, "警告！", "无有效单据条目！");
        return;
    }

    for(DingdanDetail *detail:dingdan.details){
        if(detail->count == 0){
            Product *product = detail->getProduct();
            QMessageBox::warning(
                        widget,
                        "警告！",
                        QString("商品名称：%1，商品名称：%2，数量为0，请核实！")
                        .arg(product->name)
                        .arg(product->type));
            return;
        }
    }

    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        emit this->calculateDingdanSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->calculateDingdan(dingdan);
}

void DingdanService::queryDingdan(
        QWidget *widget,
        int type,
        QString targetUsername,
        QString startDate,
        QString endDate){
    manager=  new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QList<Dingdan*> dingdans;
        for(QJsonValue obj:data.value("dingdans").toArray()){
            Dingdan *dingdan = new Dingdan();
            dingdan->loadFromJsonObject(obj.toObject());
            dingdans.append(dingdan);
        }
        emit this->queryDingdanSuccess(dingdans);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->queryDingdan(type, User::getUsername(), targetUsername, startDate, endDate);
}

void DingdanService::queryDingdanDetail(
        QWidget *widget,
        int type,
        QString targetUsername,
        QString productId,
        QString startDate,
        QString endDate){
    manager=  new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray dingdanArr = data.value("dingdans").toArray();
        QJsonArray detailArr = data.value("details").toArray();
        QList<DingdanAndDetail*> details;
        for(int i=0; i<dingdanArr.size(); i++){
            DingdanAndDetail *detail = new DingdanAndDetail();
            detail->dingdan.loadFromJsonObject(dingdanArr[i].toObject());
            detail->detail.loadFromJsonObject(detailArr[i].toObject());
            details.append(detail);
        }
        emit this->queryDingdanDetailSuccess(details);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->queryDingdanDetail(
                type,
                User::getUsername(),
                targetUsername,
                productId,
                startDate,
                endDate);
}

QList<Dingdan*> DingdanService::queryDingdan(
        QList<Dingdan*> currentDingdans,
        UserRelation::RelationType widgetType,
        int ticketType,
        int moneyType){
    if(currentDingdans.size() == 0 || (ticketType == 0 && moneyType == 0)){
        return currentDingdans;
    }

    QList<Dingdan*> resultDingdans;
    for(Dingdan *dingdan:currentDingdans){
        if(widgetType == UserRelation::Client){
            if(checkTicketAndMoneyValue(
                        dingdan->ticketOut,
                        dingdan->moneyIn,
                        ticketType,
                        moneyType)){
                resultDingdans.append(dingdan);
            }
        }else{
            if(checkTicketAndMoneyValue(
                        dingdan->ticketIn,
                        dingdan->moneyOut,
                        ticketType,
                        moneyType)){
                resultDingdans.append(dingdan);
            }
        }
    }

    return resultDingdans;
}

bool DingdanService::checkTicketAndMoneyValue(
        double ticket,
        double money,
        int ticketType,
        int moneyType){
    if(ticketType ==0 && moneyType ==1){
        //No Ticket and Money Clear
        return money == 0.0;
    }else if(ticketType == 0 && moneyType == 2){
        //No Ticket and Money UnClear
        return money != 0.0;
    }else if(ticketType == 1 && moneyType == 0){
        //Ticket Clear and No Money
        return ticket==0.0;
    }else if(ticketType == 1 && moneyType == 1){
        //Ticket Clear and Money Clear
        return ticket==0.0 && money==0.0;
    }else if(ticketType == 1 && moneyType == 2){
        //Ticket Clear and Money UnClear
        return ticket==0.0 && money!=0.0;
    }else if(ticketType == 2 && moneyType == 0){
        //Ticket UnClear and No Money
        return ticket!=0.0;
    }else if(ticketType == 2 && moneyType == 1){
        //Ticket UnClear and Money Clear
        return ticket!=0.0 && money==0.0;
    }else if(ticketType == 2 && moneyType == 2){
        //Ticket UnClear and Money UnClear
        return ticket!=0.0 && money!=0.0;
    }else{
        return false;
    }
}

QList<DingdanAndDetail*> DingdanService::queryDingdanDetail(
        QList<DingdanAndDetail*> currentDetais,
        UserRelation::RelationType widgetType,
        int ticketType,
        int moneyType){
    if(currentDetais.size() == 0 || (ticketType == 0 && moneyType==0)){
        return currentDetais;
    }

    QList<DingdanAndDetail*> resultDetails;
    for(DingdanAndDetail *detail:currentDetais){
        if(widgetType == UserRelation::Client){
            if(checkTicketAndMoneyValue(
                        detail->detail.ticketOut,
                        detail->detail.moneyIn,
                        ticketType,
                        moneyType)){
                resultDetails.append(detail);
            }
        }else{
            if(checkTicketAndMoneyValue(
                        detail->detail.ticketIn,
                        detail->detail.moneyOut,
                        ticketType,
                        moneyType)){
                resultDetails.append(detail);
            }
        }
    }

    return resultDetails;
}

void DingdanService::getDingdanDetails(QWidget *widget, Dingdan::FinanceWidgetType type, QString targetUsername){
    manager=  new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray dingdanArr = data.value("dingdans").toArray();
        QJsonArray detailArr = data.value("details").toArray();
        QList<DingdanAndDetail*> details;
        for(int i=0; i<dingdanArr.size(); i++){
            DingdanAndDetail *detail = new DingdanAndDetail();
            detail->dingdan.loadFromJsonObject(dingdanArr[i].toObject());
            detail->detail.loadFromJsonObject(detailArr[i].toObject());
            details.append(detail);
        }
        emit this->getDingdanDetailByTypeSuccess(details);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getDingdanDetails(type, User::getUsername(), targetUsername);
}

void DingdanService::financeSubmit(
        QWidget *widget,
        QPushButton *button,
        Dingdan::FinanceWidgetType type,
        QString relatedMessageId,
        UserRelation *relation,
        double curPreSave,
        double totalFinanceGive,
        double totalFinanceMake,
        double totalFinanceNeed,
        QList<DingdanDetail*> details){
    if(relation == nullptr){
        QMessageBox::warning(widget, "警告", "未选择客户或供应商！");
        return;
    }

    QString typeName = Dingdan::getFinanceWidgetTypeStr(type);
    QString preSaveStr = Dingdan::getFinancePreSaveStr(type);

    if((totalFinanceGive+curPreSave < totalFinanceMake)||
            (totalFinanceGive+curPreSave > totalFinanceMake && totalFinanceMake < totalFinanceNeed)){
        QMessageBox::warning(widget, "警告", QString("分配%1与本次%2不符！").arg(typeName).arg(typeName));
        return;
    }

    double preSave = totalFinanceGive + curPreSave - totalFinanceMake;
    bool ok = QMessageBox::question(
                widget,
                "信息",
                QString("本次%1：%2,%3：%4,是否提交？").arg(typeName).arg(totalFinanceMake).arg(preSaveStr).arg(preSave),
                tr("确定"),
                tr("取消"));
    if(ok == 0){
        manager = new DingdanNetworkAccessManager();

        connect(manager, &BaseNetworkAccessManager::onSuccess,
                [=](QString message)
        {
            button->setEnabled(true);
            QMessageBox::information(widget, "信息", message);
            this->financeSubmitSuccess();
        });

        connect(manager, &BaseNetworkAccessManager::onFailed,
                [=](QString message)
        {
            button->setEnabled(true);
            QMessageBox::warning(widget, "警告", message);
        });

        button->setEnabled(false);
        manager->financeSubmit(
                    Company::getCompanyId(),
                    User::getUsername(),
                    relation->targetUsername,
                    relatedMessageId,
                    relation->type,
                    type,
                    curPreSave,
                    preSave,
                    totalFinanceGive,
                    details);
    }
}

void DingdanService::getHistoryProducts(
        QWidget *widget,
        int type,
        UserRelation *relation,
        Product *product){
    if(relation == nullptr && product == nullptr){
        QMessageBox::warning(widget, "警告", "请选择用户或商品！");
        return;
    }

    QString targetCompanyId = relation==nullptr?"":relation->targetCompanyId;
    QString sourceProductId = product==nullptr?"":product->productId;

    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QList<HistoryProduct*> historyProducts;
        QJsonArray historyProductArr = data.value("historyProducts").toArray();
        QJsonArray companyArr = data.value("companyList").toArray();

        for(int i=0; i<historyProductArr.size(); i++){
            HistoryProduct* historyProduct = new HistoryProduct();
            historyProduct->loadFromJsonObject(historyProductArr[i].toObject());
            historyProduct->targetCompany.loadFromJsonObject(companyArr[i].toObject());
            historyProducts.append(historyProduct);
        }

        if(type == 0){
            emit this->getSaleHistoryProductsSuccess(historyProducts);
        }else{
            emit this->getPurchaseHistoryProductsSuccess(historyProducts);
        }
    });

    manager->getHistoryProducts(
                User::getCompanyId(),
                targetCompanyId,
                sourceProductId,
                type);
}

void DingdanService::getImportDingdans(QWidget *widget, Dingdan::DingdanState state){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QList<Dingdan*> dingdans;
        for(QJsonValue objValue:data.value("dingdans").toArray()){
            Dingdan *dingdan = new Dingdan();
            dingdan->loadFromJsonObject(objValue.toObject());
            dingdans.append(dingdan);
        }

        emit this->getImportDingdanSuccess(dingdans);
    });

    manager->getImportDingdans(User::getUsername(), state);
}

void DingdanService::getImportDingdanDetails(
        QWidget *widget,
        QString targetUsername,
        QString targetCompanyId,
        QString dingdanId,
        int type){
    manager = new DingdanNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray sourceDetailsArr = data.value("sourceDetails").toArray();
        QJsonArray targetDetailsArr = data.value("targetDetails").toArray();
        QJsonArray sourceProductsArr = data.value("sourceProducts").toArray();
        QJsonArray targetProductsArr = data.value("targetProducts").toArray();
        QList<DingdanDetail*> sourceDetails;
        QList<DingdanDetail*> targetDetails;
        QList<Product*> sourceProducts;
        QList<Product*> targetProducts;
        for(int i=0;i<sourceDetailsArr.size();i++){
            DingdanDetail *sourceDetail = new DingdanDetail();
            DingdanDetail *targetDetail = new DingdanDetail();
            Product *sourceProduct = new Product();
            Product *targetProduct = new Product();
            sourceDetail->loadFromJsonObject(sourceDetailsArr[i].toObject());
            targetDetail->loadFromJsonObject(targetDetailsArr[i].toObject());
            sourceProduct->loadFromJsonObject(sourceProductsArr[i].toObject());
            targetProduct->loadFromJsonObject(targetProductsArr[i].toObject());
            sourceDetails.append(sourceDetail);
            targetDetails.append(targetDetail);
            sourceProducts.append(sourceProduct);
            targetProducts.append(targetProduct);
        }

        emit this->getImportDingdanDetailSuccess(
                    sourceDetails,
                    targetDetails,
                    sourceProducts,
                    targetProducts);
    });

    manager->getImportDingdanDetails(
                User::getUsername(),
                targetUsername,
                User::getCompanyId(),
                targetCompanyId,
                dingdanId,
                type);
}
